package zzk.activiti.实战;

import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 实例模块
 */
@Controller
@RequestMapping("execution")
public class 流程2_实例模块 {
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private HistoryService historyService;

    /**
     * 1.启动流程
     * 需要将流程里面的到达节点的变量都设置，否则会报错
     */
    @RequestMapping("addExecution")
    @ResponseBody
    public void addApplication(String processId) {
        //前段頁面根據角色
        String assignee1 = "zhanzhk";
        String role2 = "manager";
        String role3 = "bigManager";
        String role4 = "moneyer";


        Map<String, Object> variables = new HashMap<>();
        variables.put("assignee1", assignee1);
        variables.put("role2", role2);
        variables.put("role3", role3);
        variables.put("role4", role4);

        Authentication.setAuthenticatedUserId(assignee1);
        ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
                .processDefinitionId(processId)  // 指定流程定义ID
                .businessKey("businessKey")     // 可选：指定业务键
                .variables(variables)           // 设置启动变量
                .start();
    }



    /**
     * 2.我的待办
     */
    @RequestMapping("myTask")
    @ResponseBody
    public void myTask(String user) {
        //查询流程定义对象
        List<Task> tasks = taskService.createTaskQuery()
                .taskAssignee(user)
                .list();

        for (Task task : tasks) {
            System.out.println("流程id：" + task.getProcessDefinitionId());
            ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
            ProcessDefinition processDefinition = processDefinitionQuery
                    .processDefinitionId(task.getProcessDefinitionId())
                    .singleResult();
            System.out.println("流程名称: " + processDefinition.getName());
            System.out.println("流程标识Key（文件定义）: " + processDefinition.getKey());

            System.out.println("实例id：" + task.getProcessInstanceId());
            //使用id获取流程实例对象
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(task.getProcessInstanceId())
                    .singleResult();
            System.out.println("实例开始时间：" + processInstance.getStartTime());


            System.out.println("节点id：" + task.getId());
            System.out.println("节点位置id：" + task.getTaskDefinitionKey());
            System.out.println("节点名称：" + task.getName());
            System.out.println("节点申请人：" + task.getAssignee());
            System.out.println("节点申请时间：" + task.getCreateTime());
            System.out.println("---------------------------------");
        }
    }

    /**
     * 3.流程提交
     */
    @RequestMapping("pass")
    @ResponseBody
    public void pass(String taskId) {
        //根据流程的key和任务负责人 查询任务
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        //完成任务，跳到下一个流程
        taskService.complete(task.getId());
    }

    /**
     * 4.审核节点-可拾取任务列表
     */
    @RequestMapping("myClaimTask")
    @ResponseBody
    public void myClaimTask() {
        String role = "manager";

        List<Task> tasks = taskService.createTaskQuery()
                .taskCandidateGroup(role)
                .list();
        System.out.println(tasks);
    }

    /**
     * 5.审核节点-拾取任务,变成我的待办
     */
    @RequestMapping("claimTask")
    @ResponseBody
    public void claimTask(String taskId) {
        String taskCandidateUser = "chenkl";
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task != null) {
            taskService.claim(task.getId(), taskCandidateUser);
        }
    }

    /**
     * 6.获取我的申请实例
     */
    @RequestMapping("myApply")
    @ResponseBody
    public void myApply(String user) {
        List<ProcessInstance> processInstances =  runtimeService.createProcessInstanceQuery().startedBy("zhanzhk").list();

        for(ProcessInstance processInstance:processInstances){
            System.out.println("实例id：" + processInstance.getProcessInstanceId());
            System.out.println("实例开始时间：" + processInstance.getStartTime());
        }
    }
    /**
     * 7.获取我的经办
     */
    @RequestMapping("myHisTask")
    @ResponseBody
    public void myHisTask(String user) {
        //通过historyServce获取任务列表
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                //添加审批人username获取特定task
                .taskAssignee(user)
//                //获取已经完成的任务
//                .finished()
                //根据结束时间进行倒序排序
                .orderByHistoricTaskInstanceEndTime()
                .desc()
                //进行分页操作
                .list();

        List<HistoricTaskInstance> resList = list.stream().filter(ht -> {
            //deleteReason为空时，表示没有撤销
            return ht.getDeleteReason() == null;
        }).collect(Collectors.toList());


        for(HistoricTaskInstance historicTaskInstance:resList){
            String instanceId=historicTaskInstance.getProcessInstanceId();

            ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
            ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionId(historicTaskInstance.getProcessDefinitionId()).singleResult();
            System.out.println("流程名称: " + processDefinition.getName());
            System.out.println("流程标识Key（文件定义）: " + processDefinition.getKey());

            ProcessInstance processInstance =  runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
            System.out.println("实例id：" + processInstance.getProcessInstanceId());
            System.out.println("实例开始时间：" + processInstance.getStartTime());
            System.out.println("发起人：" + processInstance.getStartUserId());

        }

    }

    /**
     * 8.查看实例所有任务
     */
    @RequestMapping("getTaskByInstanceId")
    @ResponseBody
    public void getTaskByInstanceId(String instanceId) {

        // 查询历史任务实例，包括已完成的任务
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(instanceId);  // 按流程实例ID过滤
        // 执行查询并获取结果
        List<HistoricTaskInstance> historicTasks = historicTaskInstanceQuery.list();
        for(HistoricTaskInstance historicTaskInstance:historicTasks){
            System.out.println("节点id："+historicTaskInstance.getId());
            System.out.println("节点名称："+historicTaskInstance.getName());
            System.out.println("节点位置："+historicTaskInstance.getTaskDefinitionKey());
            System.out.println("办理人："+historicTaskInstance.getAssignee());
            System.out.println("开始时间："+historicTaskInstance.getStartTime());
            System.out.println("办结时间："+historicTaskInstance.getEndTime());
            System.out.println("---------------------------");
        }
        System.out.println(historicTasks);
    }


}
